package cn.sky.demo.service.impl;

import cn.sky.demo.domain.ResponseResult;
import cn.sky.demo.domain.dto.AddUserDto;
import cn.sky.demo.domain.dto.LoginUserDto;
import cn.sky.demo.domain.dto.UpdateUserDto;
import cn.sky.demo.domain.dto.RegistryUserDto;
import cn.sky.demo.domain.entity.User;
import cn.sky.demo.domain.vo.PageVo;
import cn.sky.demo.domain.vo.UserVO;
import cn.sky.demo.enums.AppHttpCodeEnum;
import cn.sky.demo.mapper.UserMapper;
import cn.sky.demo.service.UserService;
import cn.sky.demo.utils.BeanCopyUtils;
import cn.sky.demo.utils.JwtUtils;
import cn.sky.demo.utils.RedisCache;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @author sky
 * @date 2025年09月15日 16:51
 * @description
 * @since 1.0.0
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService{
    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RedisCache redisCache;
    @Override
    public ResponseResult addUser(AddUserDto addUserDto) {
        User user= BeanCopyUtils.copyBean(addUserDto, User.class);
        int insert = userMapper.insert(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult updateUser(UpdateUserDto updateUserDto) {
        User user=userMapper.selectById(updateUserDto.getId());
        BeanUtils.copyProperties(updateUserDto,user);
        int update = userMapper.updateById(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult deleteUser(Long id) {
        int delete = userMapper.deleteById(id);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult getUser(Integer pageNum, Integer pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        Page<User> userPage = userMapper.selectPage(page, null);
        List<UserVO> userVOS = BeanCopyUtils.copyBeanList(userPage.getRecords(), UserVO.class);
        PageVo pageVo = new PageVo(userVOS, userPage.getTotal());
        return ResponseResult.okResult(pageVo);
    }

    @Override
    public ResponseResult registryUser(RegistryUserDto registryUserDto) {
        String password = registryUserDto.getPassword();
        String salt = registryUserDto.getSalt();
        String md5Password = DigestUtils.md5DigestAsHex((password + salt).getBytes());
        registryUserDto.setPassword(md5Password);
        User user=BeanCopyUtils.copyBean(registryUserDto, User.class);
        userMapper.insert(user);
        return ResponseResult.okResult();
    }

    @Override
    public ResponseResult login(LoginUserDto loginUserDto) {
        String username = loginUserDto.getUsername();
        String password = loginUserDto.getPassword();
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername,username);
        User user = userMapper.selectOne(queryWrapper);
        String md5Password = DigestUtils.md5DigestAsHex((password + user.getSalt()).getBytes());
        if (!md5Password.equals(user.getPassword())){
            return ResponseResult.errorResult(AppHttpCodeEnum.LOGIN_ERROR);
        }
        String token = JwtUtils.createToken(user.getId());
        redisCache.setCacheObject("TOKEN_" + token, JSON.toJSONString(user), 1, TimeUnit.DAYS);
        return ResponseResult.okResult(token);
    }
    @Override
    public User checkToken(String token) {
        if (StringUtils.isEmpty(token)) {
            return null;
        }
        Map<String, Object> map = JwtUtils.checkToken(token);
        if (map == null) {
            return null;
        }

        String userJson =  redisCache.getCacheObject("TOKEN_" + token);
        if (StringUtils.isEmpty(userJson)) {
            return null;
        }
        User user = JSON.parseObject(userJson, User.class);
        return user;
    }


    @Override
    public cn.sky.demo.test.User authenticate(String username, String password) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
        if (user == null) {
            return null;
        }
        String md5Password = DigestUtils.md5DigestAsHex((password + user.getSalt()).getBytes());
        if (!md5Password.equals(user.getPassword())) {
            return null;
        }
        return BeanCopyUtils.copyBean(user, cn.sky.demo.test.User.class);
    }


    @Override
    public void saveRefreshToken(Long id, String refreshToken, int i) {

    }

    @Override
    public cn.sky.demo.test.User findUserByRefreshToken(String refreshToken) {
        return null;
    }

    @Override
    public void removeRefreshToken(String refreshToken) {

    }
}
